import { diff_match_patch, patch_obj } from 'diff-match-patch';

export interface FileDiff {
  path: string;
  timestamp: number;
  patches: patch_obj[];
  originalHash: string;
}

export class DiffService {
  private dmp: diff_match_patch;

  constructor() {
    this.dmp = new diff_match_patch();
  }

  /**
   * 计算两个文本之间的差异
   * @param oldText 原始文本
   * @param newText 新文本
   * @returns 差异补丁数组
   */
  computeDiff(oldText: string, newText: string): patch_obj[] {
    // 确保输入是字符串
    if (typeof oldText !== 'string' || typeof newText !== 'string') {
      console.error('[DiffService] Invalid input types:', {
        oldTextType: typeof oldText,
        newTextType: typeof newText,
      });
      throw new Error('Both oldText and newText must be strings');
    }

    try {
      const patches = this.dmp.patch_make(oldText, newText);
      return patches;
    } catch (error) {
      console.error('[DiffService] Error computing diff:', error);
      throw error;
    }
  }

  /**
   * 应用差异补丁到文本
   * @param text 原始文本
   * @param patches 差异补丁数组
   * @returns [应用补丁后的文本, 是否应用成功的数组]
   */
  applyDiff(text: string, patches: patch_obj[]): [string, boolean[]] {
    return this.dmp.patch_apply(patches, text);
  }

  /**
   * 将补丁转换为文本格式
   * @param patches 差异补丁数组
   * @returns 补丁文本
   */
  serializePatches(patches: patch_obj[]): string {
    return this.dmp.patch_toText(patches);
  }

  /**
   * 将补丁文本转换为补丁对象
   * @param patchText 补丁文本
   * @returns 差异补丁数组
   */
  deserializePatches(patchText: string): patch_obj[] {
    return this.dmp.patch_fromText(patchText);
  }

  /**
   * 创建文件差异对象
   * @param path 文件路径
   * @param oldText 原始文本
   * @param newText 新文本
   * @param originalHash 原始文件的哈希值
   * @returns 文件差异对象
   */
  createFileDiff(path: string, oldText: string, newText: string, originalHash: string): FileDiff {
    const patches = this.computeDiff(oldText, newText);
    return {
      path,
      timestamp: Date.now(),
      patches,
      originalHash,
    };
  }
}
